#include "head.h"  
  
extern struct attack_stats attack;  
extern int SNIFFER_MODE;  
extern int packetfd;  
extern struct trafflog log;  
  
extern char old_log_buff[];      
extern int  old_log_buff_count;  
  
struct status  
{  
   struct   status *next;  
   __u16    saddr;  
   __u16    daddr;  
   unsigned long    count;  
   char     *start_time;  
   char     *end_time;  
};  
  
struct openport  
{  
   struct openport *next;  
   __u16      port;   
} ;  
  
struct openport *portlist_head;  
struct openport *portlist_tail;  
  
void process_tcp(const struct sbuff *sbuffptr)   
{  
   struct tcphdr *tcph=sbuffptr->h.tcph;  
   struct iphdr *iph=sbuffptr->nh.iph;  
     
  
   if( SNIFFER_MODE)  
    print_tcph(tcph);  
     
   if(tcph->syn&&!tcph->ack) {  
    attack.synflood++;  
    if(!attack.synflood)  
          memcpy(&attack.synsbuff,sbuffptr,sizeof(struct sbuff));  
   }      
  
   check_scan_tcp(sbuffptr);  
   check_dos_land(sbuffptr);  
   check_dos_winnuke(sbuffptr);  
   check_dos_longurl(sbuffptr);  
   check_probe_cgi(sbuffptr);  
  
}  
  
  
void process_udp(const struct sbuff *sbuffptr)  
{  
   struct udphdr *udph=sbuffptr->h.udph;  
  
   if( SNIFFER_MODE)  
    print_udph(udph);  
 }  
  
void process_icmp(const struct sbuff *sbuffptr)  
{  
   struct icmphdr *icmph=sbuffptr->h.icmph;  
   if(SNIFFER_MODE)  
    print_icmph(icmph);  
}  
  
  
void process_igmp(const struct sbuff *sbuffptr)  
{  
}  
  
  
void check_dos_land(const struct sbuff *sbuffptr)  
{  
  
   struct iphdr *iph=sbuffptr->nh.iph;  
   struct tcphdr *tcph=sbuffptr->h.tcph;  
  
   if(!tcph->syn)       
    return;  
   if(iph->saddr!=iph->daddr || tcph->source!=tcph->dest)  
        return;  
   do_log("land",sbuffptr);  
  
}  
  
void check_dos_winnuke(const struct sbuff *sbuffptr)  
{  
   struct tcphdr *tcph=sbuffptr->h.tcph;  
  
   if(ntohs(tcph->dest)==139&&tcph->urg)  
    do_log("winnuke",sbuffptr);  
}  
  
void check_dos_longurl(const struct sbuff *sbuffptr)  
{  
   struct tcphdr *tcph=sbuffptr->h.tcph;  
   char *data=sbuffptr->data;  
  
   if(ntohs(tcph->dest)!=80 || !tcph->ack)  
    return;  
  
   if(strlen(data)>=MAX_URL_LEN){  
    do_log("Too_long_url",sbuffptr);  
    printf("%s",data);  
   }  
}  
  
void check_probe_cgi(const struct sbuff *sbuffptr)  
{  
     
   struct tcphdr *tcph=sbuffptr->h.tcph;  
   char *data=sbuffptr->data;  
  
   if(ntohs(tcph->dest)!=80||!tcph->ack||!tcph->psh)  
    return;     
    
   if((char *)strcasestr(data,"showcode.asp")!=NULL)  
    do_log("showcode",sbuffptr);  
   if((char *)strcasestr(data,"phf?")!=NULL)  
    do_log("phf",sbuffptr);  
   if((char *)strcasestr(data,"/glimpse")!=NULL)  
    do_log("glimpse_cgi",sbuffptr);  
   if((char *)strcasestr(data,"/htmlscript")!=NULL)  
    do_log("htmlscript",sbuffptr);  
   if((char *)strcasestr(data,"/bin/sh")!=NULL)  
    do_log("/bin/sh",sbuffptr);  
   if((char *)strcasestr(data,"test")!=NULL)  
    do_log("test",sbuffptr);  
   if((char *)strcasestr(data,"asp..")!=NULL)  
    do_log("asp..",sbuffptr);  
}  
  
void check_scan_tcp(const struct sbuff *sbuffptr)  
{  
   struct tcphdr *tcph=sbuffptr->h.tcph;  
   char alter[100];  
  
   if(tcph->syn&&!tcph->ack&&!findport(ntohs(tcph->dest))){  
    snprintf(alter,sizeof(alter),"SYN_to_unopen_port%d",ntohs(tcph->dest));  
    do_log(alter,sbuffptr);  
   }  
   if(tcph->res2)  
    do_log("queso",sbuffptr);  
   if(tcph->fin&&tcph->syn&&!tcph->rst&&!tcph->psh&&!tcph->ack&&!tcph->urg)  
        do_log("SF_scan",sbuffptr);  
   if(!tcph->fin&&!tcph->syn&&!tcph->rst&&!tcph->psh&&!tcph->ack&&!tcph->urg)  
        do_log("NULL_scan",sbuffptr);  
   if(tcph->fin&&tcph->syn&&tcph->rst&&tcph->psh&&tcph->ack&&tcph->urg)  
        do_log("FULL_Xmas_scan",sbuffptr);  
   if(tcph->fin&&!tcph->syn&&!tcph->rst&&tcph->psh&&!tcph->ack&&tcph->urg)  
        do_log("XMAS_Scan(FPU)",sbuffptr);  
       
}  
  
  
  
void check_dos_pingofdeath(const struct sbuff *sbuffptr)  
{  
  
   struct iphdr *iph=sbuffptr->nh.iph;  
  
   if(iph->protocol!=1) return;  
   do_log("Ping_of_death",sbuffptr);  
  
}  
  
  
void stats()  
{  
   struct sbuff *sbuffptr;  
  
   if(attack.synflood>MAX_SYN){  
    sbuffptr=&attack.synsbuff;    
    do_log("synflood",sbuffptr);  
   }      
   
   bzero(&attack,sizeof(attack));  
   alarm(1);  
}  
  
void print_iph(const struct iphdr *iph)  
{      
   printf("ip ver=%d\n",iph->version);  
   printf("ip ihl=%d bytes\n",iph->ihl<<2);  
   printf("ip tos=%d\n",iph->tos);  
   printf("ip tot_len=%d\n",ntohs(iph->tot_len));  
   printf("ip id=%d",ntohs(iph->id));  
   printf(" %c ",(iph->frag_off&htons(IP_MF))?'M':'-');  
   printf("ip frag_off=ox%x",ntohs(iph->frag_off&htons(IP_OFFSET)));  
   printf("ip ttl=%d",iph->ttl);  
   printf("ip protocol=%d\n",iph->protocol);  
   printf("From %s  ",inet_ntoa(iph->saddr));  
   printf("To %s\n",inet_ntoa(iph->daddr));  
}  
  
void print_tcph(const struct tcphdr *tcph)  
{  
   printf("tcp sourse=%d\n",ntohs(tcph->source));  
   printf("tcp dest=%d\n",ntohs(tcph->dest));  
   printf("%c",tcph->fin==1?'F':'*');  
   printf("%c",tcph->syn==1?'S':'*');  
   printf("%c",tcph->rst==1?'R':'*');  
   printf("%c",tcph->psh==1?'P':'*');  
   printf("%c",tcph->ack==1?'A':'*');  
   printf("%c",tcph->urg==1?'U':'*');  
   printf(" Tcp seq=%ld\n",ntohl(tcph->seq));  
   printf(" Tcp ack_seq=%d\n",ntohl(tcph->ack_seq));   
   printf("window=%d\n",ntohs(tcph->window));  
}  
  
void print_udph(const struct udphdr *udph)  
{  
   printf("udp sourse=%d\n",ntohs(udph->source));  
   printf("udp dest=%d\n",ntohs(udph->dest));   
}  
  
void print_icmph(const struct icmphdr *icmph)  
{  
}  
  
void err_quit(char * errbuff)  
{  
   printf(errbuff);  
   exit(-2);  
}   
  
static char * fillspace(char * string)  /*used in do_log()*/  
{  
   int i;  
   for(i=0;string[i];i++){  
      if(string[i]==' ')   string[i]='_';  
   }     
   return string;  
}  
  
void do_log(char *msg,const struct sbuff *sb)  
{  
        time_t    ticks;  
        char      sendbuff[MAXBUFFSIZE];  
    struct    iphdr  *iph=sb->nh.iph;  
  
  
        printf("old_log_buff=%s\n",old_log_buff);  
      
    if(!strcmp(old_log_buff,msg)){   
        old_log_buff_count++;  
                printf("old_log_buff_count=%d\n",old_log_buff_count);  
        return;  
    }  
          
        if(old_log_buff_count) {  
    ticks=time(NULL);  
        bzero(sendbuff,sizeof(sendbuff));  
      
        snprintf(sendbuff,sizeof(sendbuff),  
                 "%s %s %s %d %s",  
           
                 inet_ntoa(iph->saddr),  
                 inet_ntoa(iph->daddr),  
         "the last message repeated",  
         old_log_buff_count,  
                 fillspace((char *)ctime(&ticks))  
                 );  
if(fputs(sendbuff,logfd)==EOF)     
    err_quit("fputs");  
        }  
  
    old_log_buff_count=0;  
    if(strncpy(old_log_buff,msg,MAXBUFFSIZE)==NULL){  
            printf("strncpy error\n");  
    }  
        printf("old_log_buff now:%s\n",old_log_buff);  
    ticks=time(NULL);  
        bzero(sendbuff,sizeof(sendbuff));  
              
        snprintf(sendbuff,sizeof(sendbuff),  
                 "%s %s %s %s",  
           
                 inet_ntoa(iph->saddr),  
                 inet_ntoa(iph->daddr),  
         msg,  
     
                 fillspace((char *)ctime(&ticks))  
                 );  
if(fputs(sendbuff,logfd)==EOF)     
    err_quit("fputs");  
    return;  
  
}  
  
  
void  final_quit()  
{  
   struct ifreq ifr;  
   strcpy(ifr.ifr_name,"eth0");  
   if(ioctl(packetfd,SIOCGIFFLAGS,&ifr)<0)  
      err_quit("ioctl1");  
   ifr.ifr_flags&=~IFF_PROMISC;  
   if(ioctl(packetfd,SIOCSIFFLAGS,&ifr)<0)  
      err_quit("Can not exit PROMISC mode\n");  
   printf("\n%ld IP packet received\n",log.ippacket);  
   printf("%ld Bad IP packet\n",log.bad_ippacket);  
   printf("%ld TCP packets\n",log.tcppacket);  
   printf("%ld UDP packets\n",log.udppacket);  
   printf("%ld ICMP packets\n",log.icmppacket);  
   printf("%ld IGMP packets\n",log.igmppacket);  
   printf("%ld Unknow packets\n",log.unknownpacket);  
   printf("%ld Fragment\n",log.fragment);  
   printf("%ld Total bytes\n",log.totalbytes);     
   printf("Bye!\n");  
   exit(0);  
      
}  
  
  
int findport(__u16 port)  
{  
   int i=0;  
   struct openport *temp;  
     
   if(portlist_head->port==1){  
    i=1;  
    return i;  
   }  
  
   for(temp=portlist_head->next;temp;temp=temp->next)  
        if(port==temp->port) {  
        i=1;  
        break;  
    }  
     
   return i;  
         
}  
  
static void add_port_to_list(__u16 port)  
{  
   struct openport *temp=malloc(sizeof(struct openport));  
   temp->port=port;  
   temp->next=NULL;  
   portlist_tail->next=temp;  
   portlist_tail=temp;  
}  
  
void process_cfg()  
{  
  
   FILE *fp;  
   char i[100];  
   int  t;  
   __u16 dport;  
  
   portlist_head=malloc(sizeof(struct openport));  
   portlist_tail=portlist_head;  
   portlist_head->port=0;  
   portlist_head->next=NULL;  
  
   fp=fopen("./openport.conf","r");  
   if(!fp){  
    printf("openport.conf is not exist:all port is defined open.\n");  
    portlist_head->port=1;  
    return;   
   }  
  
   for(t=0;t<3000;t++){  
      bzero(i,sizeof(i));  
      if(fgets(i,sizeof(i),fp)==NULL) break;  
        
      if(i[0]=='#'||i[0]=='\n'||!isdigit(i[0]))  continue;  
      dport=(__u16)atoi(i);   
      if(dport){  
    add_port_to_list(dport);  
        printf("Add port %d to openport list\n",dport);  
      }   
   }   
}  